home *** CD-ROM | disk | FTP | other *** search
/ Aminet 19 / Aminet 19 (1997)(GTI - Schatztruhe)[!][Jun 1997].iso / Aminet / gfx / conv / DumpDTAnim013.lha / dumpdtanim / dumpdtanim.c < prev    next >
C/C++ Source or Header  |  1997-01-05  |  42KB  |  1,333 lines

  1.  
  2.  
  3. /*
  4. **
  5. **  $VER: dumpdtanim.c 1.3 (5.1.97)
  6. **  dumpdtanim 1.3
  7. **
  8. **  main file
  9. **
  10. **  (C) Copyright 1996/97 by Roland 'Gizzy' Mainz
  11. **          All Rights Reserved
  12. **
  13. */
  14.  
  15.  
  16. /* amiga includes */
  17. #include <exec/types.h>
  18. #include <exec/memory.h>
  19. #include <exec/execbase.h>
  20. #include <exec/libraries.h>
  21. #include <dos/dos.h>
  22. #include <dos/dosextens.h>
  23. #include <datatypes/datatypes.h>
  24. #include <datatypes/datatypesclass.h>
  25. #include <datatypes/soundclass.h>
  26. #include <datatypes/pictureclass.h>
  27. #include <datatypes/animationclass.h>
  28. #include <workbench/workbench.h>
  29.  
  30. /* amiga prototypes */
  31. #include <clib/macros.h>
  32. #include <clib/exec_protos.h>
  33. #include <clib/dos_protos.h>
  34. #include <clib/iffparse_protos.h>
  35. #include <clib/icon_protos.h>
  36. #include <clib/graphics_protos.h>
  37. #include <clib/intuition_protos.h>
  38. #include <clib/datatypes_protos.h>
  39. #include <clib/dtclass_protos.h>
  40. #include <clib/alib_protos.h>
  41.  
  42. /* amiga pragmas */
  43. #include <pragmas/exec_pragmas.h>
  44. #include <pragmas/dos_pragmas.h>
  45. #include <pragmas/iffparse_pragmas.h>
  46. #include <pragmas/icon_pragmas.h>
  47. #include <pragmas/graphics_pragmas.h>
  48. #include <pragmas/intuition_pragmas.h>
  49. #include <pragmas/datatypes_pragmas.h>
  50. #include <pragmas/dtclass_pragmas.h>
  51.  
  52. /* ansi includes */
  53. #include <string.h>
  54.  
  55. /*****************************************************************************/
  56.  
  57. /* IFF FILM ID */
  58. #ifndef ID_FILM
  59. #define ID_FILM MAKE_ID( 'F', 'I', 'L', 'M' )
  60. #endif /* !ID_FILM */
  61.  
  62. /* CAT CELL, a single IFF FILM frame (bitmap and sound) */
  63. #ifndef ID_CELL
  64. #define ID_CELL MAKE_ID( 'C', 'E', 'L', 'L' )
  65. #endif /* !ID_CELL */
  66.  
  67. /* body, used by CELLs ILBM and 8SVX */
  68. #ifndef ID_BODY
  69. #define ID_BODY MAKE_ID( 'B', 'O', 'D', 'Y' )
  70. #endif /* !ID_BODY */
  71.  
  72. /* IFF ILBM */
  73. #ifndef ID_ILBM
  74. #define ID_ILBM MAKE_ID( 'I', 'L', 'B', 'M' )
  75. #endif /* !ID_ILBM */
  76.  
  77. /* ILBM BMHD (bitmap header) */
  78. #ifndef ID_BMHD
  79. #define ID_BMHD MAKE_ID( 'B', 'M', 'H', 'D' )
  80. #endif /* !ID_BMHD */
  81.  
  82. /* ILBM CMAP (color map) */
  83. #ifndef ID_CMAP
  84. #define ID_CMAP MAKE_ID( 'C', 'M', 'A', 'P' )
  85. #endif /* !ID_CMAP */
  86.  
  87. /* ILBM CAMG (view mode id) */
  88. #ifndef ID_CAMG
  89. #define ID_CAMG MAKE_ID( 'C', 'A', 'M', 'G' )
  90. #endif /* !ID_CMAP */
  91.  
  92. /* IFF 8SVX */
  93. #ifndef ID_8SVX
  94. #define ID_8SVX MAKE_ID( '8', 'S', 'V', 'X' )
  95. #endif /* !ID_8SVX */
  96.  
  97. /* 8SVX VHDR (VoiceHeader) */
  98. #ifndef ID_VHDR
  99. #define ID_VHDR MAKE_ID( 'V', 'H', 'D', 'R' )
  100. #endif /* !ID_VHDR */
  101.  
  102. /* 8SVX CHAN (left/right/stereo channel) */
  103. #ifndef ID_CHAN
  104. #define CHAN_RIGHT  (4L)
  105. #define CHAN_LEFT   (2L)
  106. #define CHAN_STEREO (6L)  /* CHAN_RIGHT + CHAN_LEFT */
  107.  
  108. #define ID_CHAN MAKE_ID( 'C', 'H', 'A', 'N' )
  109. #endif /* !ID_CHAN */
  110.  
  111. /*****************************************************************************/
  112.  
  113. /* from <iffp/ilbm.h>*/
  114. /* BMHD flags */
  115.  
  116. /* Advisory that 8 significant bits-per-gun have been stored in CMAP
  117.  * i.e. that the CMAP is definitely not 4-bit values shifted left.
  118.  * This bit will disable nibble examination by color loading routine.
  119.  */
  120. #define BMHDB_CMAPOK (7U)
  121. #define BMHDF_CMAPOK (1U << BMHDB_CMAPOK)
  122.  
  123. /*****************************************************************************/
  124.  
  125. extern struct ExecBase  *SysBase;
  126. extern struct Library   *DOSBase;
  127.        struct Library   *IFFParseBase;
  128.        struct Library   *IconBase;
  129.        struct Library   *GfxBase;
  130.        struct Library   *IntuitionBase;
  131.        struct Library   *DataTypesBase;
  132.  
  133. /*****************************************************************************/
  134.  
  135.  
  136. #define TEMPLATE "NAME/A,"                           \
  137.                  "MOVIE/S,"                          \
  138.                  "STARTFRAME/K/N,"                   \
  139.                  "STOPFRAME/K/N,"                    \
  140.                  "SKIPFRAMES/K/N,"                   \
  141.                  "IFFFILM=FILM/K,"                   \
  142.                  "CLIPIFFFILM=CLIPFILM/S,"           \
  143.                  "CLIPIFFFILMUNIT=CLIPFILMUNIT/K/N," \
  144.                  "PICTUREPERFRAME/S,"                \
  145.                  "SAMPLEPERFRAME=SPF/S,"             \
  146.                  "GLOBALSAMPLE/S"
  147.  
  148. #define OPT_NAME             (0)
  149. #define OPT_MOVIE            (1)
  150. #define OPT_STARTFRAME       (2)
  151. #define OPT_STOPFRAME        (3)
  152. #define OPT_SKIPFRAMES       (4)
  153. #define OPT_IFFFILM          (5)
  154. #define OPT_CLIPIFFFILM      (6)
  155. #define OPT_CLIPIFFFILMUNIT  (7)
  156. #define OPT_PICTUREPERFRAME  (8)
  157. #define OPT_SAMPLEPERFRAME   (9)
  158. #define OPT_GLOBALSAMPLE    (10)
  159. #define NUM_OPTS            (11)
  160.  
  161. /*****************************************************************************/
  162.  
  163.  
  164. /* prototypes */
  165. long              main( void );
  166.  
  167. struct IFFHandle *OpenIFFFile( STRPTR, ULONG );
  168. BOOL              CloseIFFFile( struct IFFHandle * );
  169.  
  170. struct IFFHandle *OpenIFFClipboard( LONG );
  171. void              CloseIFFClipboard( struct IFFHandle * );
  172.  
  173. LONG              StartIFFFilm( struct IFFHandle *, struct BitMapHeader *, ULONG, struct ColorRegister *, ULONG, struct VoiceHeader * );
  174. void              EndIFFFilm( struct IFFHandle * );
  175. LONG              WriteIFFFilmCell( struct IFFHandle *, struct BitMapHeader *, struct BitMap *, BYTE *, ULONG );
  176. LONG              Put8SVXBody( struct IFFHandle *, BYTE *, ULONG );
  177. LONG              PutILBMBody( struct IFFHandle *, struct BitMap *, struct BitMapHeader * );
  178.  
  179. ULONG             SaveDTObject( Object *, struct Window *, struct Requester *, STRPTR, ULONG, struct TagItem * );
  180. void              SaveSample( STRPTR, BYTE *, ULONG, ULONG, ULONG );
  181.  
  182. void              FillColorRegisters( struct ColorRegister *, ULONG *, ULONG );
  183. void              CopyBitMap( struct BitMap *, struct BitMap * );
  184. void              mysprintf( STRPTR, STRPTR , ... );
  185.  
  186. BOOL              IsInterleavedBitMap( struct BitMap * );
  187.  
  188. /*****************************************************************************/
  189.  
  190. /* IFF errors to DOS errors */
  191. LONG ifferr2doserr[] =
  192. {
  193.   0L,                         /* End of file (not an error).                  */
  194.   0L,                         /* End of context (not an error).               */
  195.   DTERROR_INVALID_DATA,       /* No lexical scope.                            */
  196.   ERROR_NO_FREE_STORE,        /* Insufficient memory.                         */
  197.   ERROR_SEEK_ERROR,           /* Stream read error.                           */
  198.   ERROR_SEEK_ERROR,           /* Stream write error.                          */
  199.   ERROR_SEEK_ERROR,           /* Stream seek error.                           */
  200.   DTERROR_INVALID_DATA,       /* File is corrupt.                             */
  201.   DTERROR_INVALID_DATA,       /* IFF syntax error.                            */
  202.   ERROR_OBJECT_WRONG_TYPE,    /* Not an IFF file.                             */
  203.   ERROR_REQUIRED_ARG_MISSING, /* Required call-back hook missing.             */
  204.   (0xDEADDEADUL)              /* Return to client.  You should never see this */
  205. };
  206.  
  207. /*****************************************************************************/
  208.  
  209.  
  210. long main( void )
  211. {
  212.     /* Argument parsing variables */
  213.     LONG                    options[ NUM_OPTS ];
  214.     struct RDArgs          *rdargs;
  215.     LONG                    error = 0L;
  216.  
  217.     memset( options, 0, sizeof( options ) );
  218.  
  219.     IFFParseBase     = OpenLibrary( "iffparse.library",  39UL );
  220.     IconBase         = OpenLibrary( "icon.library",      39UL );
  221.     GfxBase          = OpenLibrary( "graphics.library",  39UL );
  222.     IntuitionBase    = OpenLibrary( "intuition.library", 39UL );
  223.     DataTypesBase    = OpenLibrary( "datatypes.library", 39UL );
  224.  
  225.     if( IFFParseBase && IconBase && GfxBase && IntuitionBase && DataTypesBase )
  226.     {
  227.       if( rdargs = ReadArgs( TEMPLATE, options, NULL ) )
  228.       {
  229.         STRPTR              filepart    = FilePart( (STRPTR)options[ OPT_NAME ] );
  230.         ULONG               startframe  = 0UL,  /* start at this frame                  */
  231.                             stopframe   = ~0UL, /* stop at this frame                   */
  232.                             skipframes  = 1UL;  /* skip n frames during scan            */
  233.  
  234.         struct IFFHandle   *ifffilm     = NULL, /* IFF FILM output stream (file)        */
  235.                            *clipifffilm = NULL; /* IFF FILM output stream (clipboard)   */
  236.  
  237.         Object             *o;                  /* anim/movie object */
  238.  
  239.         if( options[ OPT_STARTFRAME ] )
  240.         {
  241.           startframe = *((LONG *)options[ OPT_STARTFRAME ]);
  242.         }
  243.  
  244.         if( options[ OPT_STOPFRAME ] )
  245.         {
  246.           stopframe = *((LONG *)options[ OPT_STOPFRAME ]);
  247.  
  248.           if( stopframe < 1UL )
  249.           {
  250.             stopframe = 1UL;
  251.           }
  252.         }
  253.  
  254.         if( options[ OPT_SKIPFRAMES ] )
  255.         {
  256.           skipframes = *((LONG *)options[ OPT_SKIPFRAMES ]);
  257.  
  258.           if( skipframes < 1UL )
  259.           {
  260.             skipframes = 1UL;
  261.           }
  262.         }
  263.  
  264.         /* Open the animation/movie object */
  265.         if( o = NewDTObject( (APTR)options[ OPT_NAME ],
  266.  
  267.                              /* We will only accept sound DataTypes */
  268.                              DTA_GroupID,      ((options[ OPT_MOVIE ])?(GID_MOVIE):(GID_ANIMATION)),
  269.  
  270.                              /* No more attributes */
  271.                              TAG_DONE ) )
  272.         {
  273.           struct gpLayout         gpl;
  274.  
  275.           /* Base information */
  276.           STRPTR                  objname;
  277.  
  278.           /* Animation related */
  279.           ULONG                   animwidth,              /* width of animation */
  280.                                   animheight,             /* height of animation */
  281.                                   animdepth;              /* depth of animation */
  282.           ULONG                   anumframes = 0UL;       /* number of frames in animation */
  283.           ULONG                   afps = 0UL;
  284.  
  285.           /* Anim frame loading */
  286.           struct adtFrame         alf;                    /* method msg for ADTM_LOADFRAME */
  287.           ULONG                   timestamp;              /* timestamp to load */
  288.  
  289.           /* Animation frame picture related */
  290.           ULONG                   amodeid;                /* mode id of animation */
  291.           struct BitMapHeader    *abmh;                   /* bitmapheader of animation */
  292.           ULONG                   anumcolors;             /* number of colors in animation */
  293.           ULONG                  *acregs;                 /* ADTA_CRegs */
  294.           struct ColorRegister   *acm;                    /* ADTA_ColorRegisters struct ColorRegister array */
  295.  
  296.           TEXT                    picturefilename[ 512 ]; /* buffer for filename when writing */
  297.  
  298.           /* Anim frame sample related */
  299.           BYTE                   *asample;
  300.           ULONG                   asamplelength = 0UL;
  301.  
  302.           ULONG                   aperiod;
  303.           ULONG                   acycles;
  304.  
  305.           TEXT                    samplefilename[ 512 ];
  306.  
  307.           /* Sample build from all samples */
  308.           BYTE                   *globalsample        = NULL;
  309.           ULONG                   globalsampleoffset  = 0UL;
  310.           ULONG                   globalsamplesize    = 0UL;
  311.  
  312.           /* Get information about the object */
  313.           if( GetDTAttrs( o, DTA_ObjName,          (&objname),
  314.                              ADTA_Width,           (&animwidth),
  315.                              ADTA_Height,          (&animheight),
  316.                              ADTA_Depth,           (&animdepth),
  317.                              ADTA_Frames,          (&anumframes),
  318.                              ADTA_FramesPerSecond, (&afps),
  319.                              ADTA_ModeID,          (&amodeid),
  320.                              PDTA_BitMapHeader,    (&abmh),
  321.                              ADTA_NumColors,       (&anumcolors),
  322.                              ADTA_CRegs,           (&acregs),
  323.                              ADTA_ColorRegisters,  (&acm),
  324.                              ADTA_Cycles,          (&acycles),
  325.                              ADTA_Period,          (&aperiod),
  326.                              ADTA_Sample,          (&asample),
  327.                              ADTA_SampleLength,    (&asamplelength),
  328.                              TAG_DONE ) != 15UL )
  329.           {
  330.             Printf( "*** warning: not enough attributes to get\n" );
  331.           }
  332.  
  333.           /* Sound available ? */
  334.           if( asamplelength && aperiod )
  335.           {
  336.             struct VoiceHeader vh;
  337.  
  338.             vh . vh_OneShotHiSamples     = asamplelength;
  339.             vh . vh_RepeatHiSamples      = 0UL;
  340.             vh . vh_SamplesPerHiCycle    = 0UL;
  341.             vh . vh_SamplesPerSec        = ((SysBase -> ex_EClockFrequency) * 5UL) / aperiod;
  342.             vh . vh_Octaves              = 1UL;
  343.             vh . vh_Compression          = CMP_NONE;
  344.             vh . vh_Volume               = 0x10000UL; /* maximum volume */
  345.  
  346.             if( options[ OPT_IFFFILM ] )
  347.             {
  348.               if( ifffilm = OpenIFFFile( (STRPTR)options[ OPT_IFFFILM ], MODE_NEWFILE ) )
  349.               {
  350.                 if( error = StartIFFFilm( ifffilm, abmh, amodeid, acm, anumcolors, (&vh) ) )
  351.                 {
  352.                   Printf( "error while writing IFF FILM to file%ld\n", error );
  353.  
  354.                   CloseIFFFile( ifffilm );
  355.                   ifffilm = NULL;
  356.                 }
  357.                 else
  358.                 {
  359.                   Printf( "writing IFF FILM stream to file %s\n", (STRPTR)options[ OPT_IFFFILM ] );
  360.                 }
  361.               }
  362.               else
  363.               {
  364.                 Printf( "can't open iff file\n" );
  365.                 error = IoErr();
  366.               }
  367.             }
  368.  
  369.             if( options[ OPT_CLIPIFFFILM ] )
  370.             {
  371.               LONG unit;
  372.  
  373.               if( options[ OPT_CLIPIFFFILMUNIT ] )
  374.               {
  375.                 unit = *((LONG *)options[ OPT_CLIPIFFFILMUNIT ]);
  376.               }
  377.               else
  378.               {
  379.                 unit = PRIMARY_CLIP;
  380.               }
  381.  
  382.               if( clipifffilm = OpenIFFClipboard( unit ) )
  383.               {
  384.                 if( error = StartIFFFilm( clipifffilm, abmh, amodeid, acm, anumcolors, (&vh) ) )
  385.                 {
  386.                   Printf( "error while writing IFF FILM to clipboard %ld\n", error );
  387.  
  388.                   CloseIFFClipboard( clipifffilm );
  389.                   clipifffilm = NULL;
  390.                 }
  391.                 else
  392.                 {
  393.                   Printf( "writing IFF FILM stream to clipboard unit %ld\n", unit );
  394.                 }
  395.               }
  396.               else
  397.               {
  398.                 Printf( "can't open iff clipboard\n" );
  399.                 error = IoErr();
  400.               }
  401.             }
  402.  
  403.             if( options[ OPT_GLOBALSAMPLE ] )
  404.             {
  405.               globalsamplesize = (((asamplelength + 10UL) * anumframes) + 1024UL);
  406.               globalsample = (BYTE *)AllocVec( globalsamplesize, MEMF_PUBLIC );
  407.             }
  408.           }
  409.           else
  410.           {
  411.             if( options[ OPT_IFFFILM ] || options[ OPT_CLIPIFFFILM ] )
  412.             {
  413.               Printf( "can't create IFF FILM stream because sound is missing\n" );
  414.               error = ERROR_OBJECT_WRONG_TYPE;
  415.             }
  416.  
  417.             if( options[ OPT_GLOBALSAMPLE ] )
  418.             {
  419.               Printf( "can't create global sample because sound is missing\n" );
  420.               error = ERROR_OBJECT_WRONG_TYPE;
  421.             }
  422.           }
  423.  
  424.           /* Display any information we obtained */
  425.           if( objname )
  426.           {
  427.             Printf( "Name: \"%s\"\n", objname );
  428.           }
  429.  
  430.           /* Print info... */
  431.           Printf( "width %lu height %lu depth %lu frames %lu\n"
  432.                   "FramesPerSecond %lu modeid %lx colors %lu\n"
  433.                   "sample %lx samplelength %lu cycles %lu period %lu\n",
  434.                    animwidth, animheight, animdepth, anumframes,
  435.                    afps, amodeid, anumcolors,
  436.                    asample, asamplelength, acycles, aperiod );
  437.  
  438.           /* "Layout" animation (for those anim classes which need this,
  439.            * __NOT__ recommened)
  440.            */
  441.           gpl . MethodID    = DTM_PROCLAYOUT;
  442.           gpl . gpl_GInfo   = NULL;
  443.           gpl . gpl_Initial = 1L;
  444.  
  445.           DoMethodA( o, (Msg)(&gpl) );
  446.  
  447.           /* Start scan through animation */
  448.           for( timestamp = startframe ; (timestamp < anumframes) && (timestamp <= stopframe) ; timestamp += skipframes )
  449.           {
  450.             /* On error break */
  451.             if( error )
  452.             {
  453.               break;
  454.             }
  455.  
  456.             /* Check for CTRL_C signal... */
  457.             if( SetSignal( 0UL, 0UL ) & SIGBREAKF_CTRL_C )
  458.             {
  459.               error = ERROR_BREAK;
  460.  
  461.               break;
  462.             }
  463.  
  464.             /* reset method msg */
  465.             memset( (void *)(&alf), 0, sizeof( struct adtFrame ) );
  466.  
  467.             /* load frame */
  468.             alf . MethodID = ADTM_LOADFRAME;
  469.             alf . alf_TimeStamp = timestamp;
  470.             alf . alf_Frame     = timestamp;
  471.             DoMethodA( o, (Msg)(&alf) );
  472.  
  473.             /* print frame contents */
  474.             Printf( "frame: timestamp %lu frame %lu duration %lu bitmap %lx cmap %lx sample %lx len %lu period %lu\n",
  475.                     timestamp,
  476.                     (alf . alf_Frame),
  477.                     (alf . alf_Duration),
  478.                     (alf . alf_BitMap),
  479.                     (alf . alf_CMap),
  480.                     (alf . alf_Sample),
  481.                     (alf . alf_SampleLength),
  482.                     (alf . alf_Period) );
  483.  
  484.             /* handle picture data */
  485.             if( abmh && (alf . alf_BitMap) && options[ OPT_PICTUREPERFRAME ] )
  486.             {
  487.               ULONG          framewidth,
  488.                              frameheight,
  489.                              framedepth;
  490.               struct BitMap *bm;
  491.  
  492.               /* bitmap dimensions may not match ADTA_(Width|Height|Depth) dimentions */
  493.               framewidth  = GetBitMapAttr( (alf . alf_BitMap), BMA_WIDTH  );
  494.               frameheight = GetBitMapAttr( (alf . alf_BitMap), BMA_HEIGHT );
  495.               framedepth  = GetBitMapAttr( (alf . alf_BitMap), BMA_DEPTH  );
  496.  
  497.               /* Correct bitmap width if the OS didn't noticed that this is an interleaved bm
  498.                * GetBitMapAttr( bm, BMA_WIDTH ) will return (width * depth) instead of width.
  499.                * The following code should be future-compatible...
  500.                */
  501.               if( (!(GetBitMapAttr( (alf . alf_BitMap), BMA_FLAGS ) & BMF_INTERLEAVED)) &&
  502.                   IsInterleavedBitMap( (alf . alf_BitMap) ) )
  503.               {
  504.                 framewidth /= framedepth;
  505.               }
  506.  
  507.               /* Here we must allocate a temp chip mem bitmap because animation frames can be
  508.                * outside CHIP-MEM and picture.datatype cannot deal with non-chip-mem bitmaps...
  509.                */
  510.               if( bm = AllocBitMap( framewidth, frameheight, framedepth, 0UL, (alf . alf_BitMap) ) )
  511.               {
  512.                 Object *po;
  513.  
  514.                 /* Copy bitmap */
  515.                 CopyBitMap( bm, (alf . alf_BitMap) );
  516.  
  517.                 /* Create picture object and set it up manually (e.g. DTST_RAM) */
  518.                 if( po = NewDTObject( NULL,
  519.                                       DTA_SourceType, DTST_RAM,
  520.                                       DTA_GroupID,    GID_PICTURE,
  521.                                       TAG_DONE ) )
  522.                 {
  523.                   struct BitMapHeader *pbmh;
  524.  
  525.                   if( GetDTAttrs( po, PDTA_BitMapHeader, (&pbmh), TAG_DONE ) )
  526.                   {
  527.                     if( pbmh )
  528.                     {
  529.                       ULONG                *pcregs;
  530.                       struct ColorRegister *pcm;
  531.                       ULONG                 numcolors = (1UL << animdepth), /* note that numcolors
  532.                                                                              * may not match ADTA_NumColors
  533.                                                                              */
  534.                                             allocated_numcolors;
  535.  
  536.                       /* copy bitmapheader (RAW) from animation bmh... */
  537.                       *pbmh = *abmh;
  538.  
  539.                       /* ...and fill in attributes which may be different */
  540.                       pbmh -> bmh_Width  = framewidth;
  541.                       pbmh -> bmh_Height = frameheight;
  542.                       pbmh -> bmh_Depth  = framedepth;
  543.  
  544.                       /* we're writing a full palette, set this flag (currently NOP, but...) */
  545.                       pbmh -> bmh_Pad    = BMHDF_CMAPOK; /* also known as bmh_Flags */
  546.  
  547.                       /* Set screen mode id,
  548.                        * our bitmap and
  549.                        * the requested number of colors...
  550.                        */
  551.                       SetDTAttrs( po, NULL, NULL,
  552.                                   PDTA_ModeID,      amodeid,
  553.                                   PDTA_NumColors,   numcolors,
  554.                                   PDTA_BitMap,      bm,
  555.                                   TAG_DONE );
  556.  
  557.                       /* Get color tables (pcregs, pcm) and the allocated number of colors */
  558.                       if( GetDTAttrs( po, PDTA_CRegs,          (&pcregs),
  559.                                           PDTA_ColorRegisters, (&pcm),
  560.                                           PDTA_NumColors,      (&allocated_numcolors),
  561.                                           TAG_DONE ) == 3UL )
  562.                       {
  563.                         /* Success ? */
  564.                         if( pcregs && pcm )
  565.                         {
  566.                           ULONG i;
  567.  
  568.                           if( allocated_numcolors != numcolors )
  569.                           {
  570.                             Printf( "allocated_numcolors %lu != numcolors %lu\n", allocated_numcolors, numcolors );
  571.                           }
  572.  
  573.                           /* get colors (either from frame's colormap or from animation's palette) */
  574.                           if( alf . alf_CMap )
  575.                           {
  576.                             GetRGB32( (alf . alf_CMap), 0UL, (allocated_numcolors - 1UL), pcregs );
  577.                           }
  578.                           else
  579.                           {
  580.                             for( i = 0UL ; i < allocated_numcolors ; i++ )
  581.                             {
  582.                               pcregs[ ((i * 3) + 0) ] = acregs[ ((i * 3) + 0) ]; /* copy r, */
  583.                               pcregs[ ((i * 3) + 1) ] = acregs[ ((i * 3) + 1) ]; /*      g, */
  584.                               pcregs[ ((i * 3) + 2) ] = acregs[ ((i * 3) + 2) ]; /*      b  */
  585.                             }
  586.                           }
  587.  
  588.                           /* copy cregs to colorregisters */
  589.                           FillColorRegisters( pcm, acregs, allocated_numcolors );
  590.  
  591.                           mysprintf( picturefilename, "%s_picture_%05.5lu.ilbm", filepart, timestamp );
  592.                           Printf( "saving picture: \"%s\"\n", picturefilename );
  593.                           SaveDTObject( po, NULL, NULL, picturefilename, DTWM_IFF, NULL );
  594.                         }
  595.                         else
  596.                         {
  597.                           Printf( "picture object mem err (no color tables)\n" );
  598.                           error = ERROR_NO_FREE_STORE;
  599.                         }
  600.                       }
  601.                       else
  602.                       {
  603.                         /* can't get required args from object */
  604.                         error = ERROR_OBJECT_WRONG_TYPE;
  605.                       }
  606.  
  607.                       /* picture.datatype object will free the bitmap */
  608.                       bm = NULL;
  609.                     }
  610.                     else
  611.                     {
  612.                       Printf( "can't get bitmapheader\n" );
  613.                       error = ERROR_NO_FREE_STORE;
  614.                     }
  615.                   }
  616.                   else
  617.                   {
  618.                     /* can't get required args from object */
  619.                     Printf( "can't get PDTA_BitMapHeader\n" );
  620.                     error = ERROR_OBJECT_WRONG_TYPE;
  621.                   }
  622.  
  623.                   /* Get rid of the picture object */
  624.                   DisposeDTObject( po );
  625.                 }
  626.                 else
  627.                 {
  628.                   Printf( "can't create picture object\n" );
  629.                   error = IoErr();
  630.                 }
  631.  
  632.                 /* free temp bitmap */
  633.                 FreeBitMap( bm );
  634.               }
  635.               else
  636.               {
  637.                 Printf( "can't alloc frame bitmap\n" );
  638.                 error = ERROR_NO_FREE_STORE;
  639.               }
  640.             }
  641.  
  642.             /* handle sound/sample data */
  643.             if( alf . alf_Sample )
  644.             {
  645.               if( options[ OPT_SAMPLEPERFRAME ] )
  646.               {
  647.                 mysprintf( samplefilename, "%s_sample_%05.5lu.8svx", filepart, timestamp );
  648.                 Printf( "saving sample : \"%s\"\n", samplefilename );
  649.                 SaveSample( samplefilename, (alf . alf_Sample), (alf . alf_SampleLength), (alf . alf_Period), acycles );
  650.               }
  651.  
  652.               if( globalsample )
  653.               {
  654.                 if( globalsampleoffset < (globalsamplesize - (1000UL + (alf . alf_SampleLength))) )
  655.                 {
  656.                   CopyMem( (alf . alf_Sample), (globalsample + globalsampleoffset), (alf . alf_SampleLength) );
  657.                   globalsampleoffset += alf . alf_SampleLength;
  658.                 }
  659.                 else
  660.                 {
  661.                   Printf( "global sample buffer overflow\n" );
  662.                   error = ERROR_BUFFER_OVERFLOW;
  663.                 }
  664.               }
  665.             }
  666.  
  667.             if( ifffilm )
  668.             {
  669.               if( error = WriteIFFFilmCell( ifffilm, abmh, (alf . alf_BitMap), (alf . alf_Sample), (alf . alf_SampleLength) ) )
  670.               {
  671.                 Printf( "error while writing IFF FILM, aborted\n" );
  672.                 EndIFFFilm( ifffilm );
  673.                 CloseIFFFile( ifffilm );
  674.                 ifffilm = NULL;
  675.               }
  676.             }
  677.  
  678.             if( clipifffilm )
  679.             {
  680.               if( error = WriteIFFFilmCell( clipifffilm, abmh, (alf . alf_BitMap), (alf . alf_Sample), (alf . alf_SampleLength) ) )
  681.               {
  682.                 Printf( "error while writing IFF FILM to clipboard, aborted\n" );
  683.                 EndIFFFilm( clipifffilm );
  684.                 CloseIFFClipboard( clipifffilm );
  685.                 clipifffilm = NULL;
  686.               }
  687.             }
  688.  
  689.             alf . MethodID = ADTM_UNLOADFRAME;
  690.             DoMethodA( o, (Msg)(&alf) );
  691.           }
  692.  
  693.           /* Get rid of the anim/movie object */
  694.           DisposeDTObject( o );
  695.  
  696.           if( globalsample )
  697.           {
  698.             mysprintf( samplefilename, "%s_sample_global.8svx", filepart );
  699.             SaveSample( samplefilename, globalsample, globalsampleoffset, aperiod, acycles );
  700.  
  701.             FreeVec( globalsample );
  702.           }
  703.  
  704.           if( ifffilm )
  705.           {
  706.             EndIFFFilm( ifffilm );
  707.             CloseIFFFile( ifffilm );
  708.           }
  709.  
  710.           if( clipifffilm )
  711.           {
  712.             EndIFFFilm( clipifffilm );
  713.             CloseIFFClipboard( clipifffilm );
  714.           }
  715.         }
  716.         else
  717.         {
  718.           /* NewDTObject failed */
  719.           error = IoErr();
  720.         }
  721.  
  722.         /* Free the allocated memory after ReadArgs */
  723.         FreeArgs( rdargs );
  724.       }
  725.       else
  726.       {
  727.         /* ReadArgs failed */
  728.         error = IoErr();
  729.       }
  730.     }
  731.     else
  732.     {
  733.       /* can't open required libraries */
  734.       error = ERROR_OBJECT_NOT_FOUND;
  735.     }
  736.  
  737.     /* Error ? */
  738.     if( error )
  739.     {
  740.       TEXT errbuff[ 256 ];
  741.  
  742.       /* IFFParse error code ? */
  743.       if( error < 0L )
  744.       {
  745.         /* convert IFFParse error to DOS error */
  746.         error = ifferr2doserr[ -error - 1 ];
  747.       }
  748.  
  749.       if( error >= DTERROR_UNKNOWN_DATATYPE )
  750.       {
  751.         mysprintf( errbuff, GetDTString( error ), "file" );
  752.       }
  753.       else
  754.       {
  755.         Fault( error, NULL, errbuff, sizeof( errbuff ) );
  756.       }
  757.  
  758.       Printf( "dumpdtanim: %s\n", errbuff );
  759.     }
  760.  
  761.     CloseLibrary( DataTypesBase );
  762.     CloseLibrary( IntuitionBase );
  763.     CloseLibrary( GfxBase );
  764.     CloseLibrary( IconBase );
  765.     CloseLibrary( IFFParseBase );
  766.  
  767.     SetIoErr( error );
  768.  
  769.     return( ((error)?(RETURN_ERROR):(RETURN_OK)) );
  770. }
  771.  
  772.  
  773. struct IFFHandle *OpenIFFFile( STRPTR file, ULONG mode )
  774. {
  775.     struct IFFHandle *iff;
  776.     LONG              ioerr;
  777.  
  778.     if( file && mode )
  779.     {
  780.       if( iff = AllocIFF() )
  781.       {
  782.         /* Set up IFF_File for file I/O. */
  783.         if( iff -> iff_Stream = (ULONG)Open( file, mode ) )
  784.         {
  785.           InitIFFasDOS( iff );
  786.  
  787.           return( iff );
  788.         }
  789.         else
  790.         {
  791.           /* Open failed */
  792.           ioerr = IoErr();
  793.         }
  794.  
  795.         FreeIFF( iff );
  796.       }
  797.       else
  798.       {
  799.         /* AllocIFF failed */
  800.         ioerr = ERROR_NO_FREE_STORE;
  801.       }
  802.     }
  803.     else
  804.     {
  805.       /* wrong function args */
  806.       ioerr = ERROR_REQUIRED_ARG_MISSING;
  807.     }
  808.  
  809.     SetIoErr( ioerr );
  810.  
  811.     return( NULL );
  812. }
  813.  
  814.  
  815. BOOL CloseIFFFile( struct IFFHandle *iff )
  816. {
  817.     BOOL success = FALSE;
  818.  
  819.     if( iff )
  820.     {
  821.       success = Close( (BPTR)(iff -> iff_Stream) );
  822.  
  823.       FreeIFF( iff );
  824.     }
  825.  
  826.     return( success );
  827. }
  828.  
  829.  
  830. struct IFFHandle *OpenIFFClipboard( LONG unit )
  831. {
  832.     struct IFFHandle *iff;
  833.     LONG              ioerr;
  834.  
  835.     if( iff = AllocIFF() )
  836.     {
  837.       /* Set up IFF_File for clipboard I/O. */
  838.       if( iff -> iff_Stream = (ULONG)OpenClipboard( unit ) )
  839.       {
  840.         InitIFFasClip( iff );
  841.  
  842.         return( iff );
  843.       }
  844.       else
  845.       {
  846.         /* couldn't open clipboard */
  847.         ioerr = DTERROR_COULDNT_OPEN_CLIPBOARD;
  848.       }
  849.  
  850.       FreeIFF( iff );
  851.     }
  852.     else
  853.     {
  854.       /* AllocIFF failed */
  855.       ioerr = ERROR_NO_FREE_STORE;
  856.     }
  857.  
  858.     SetIoErr( ioerr );
  859.  
  860.     return( NULL );
  861. }
  862.  
  863.  
  864. void CloseIFFClipboard( struct IFFHandle *iff )
  865. {
  866.     if( iff )
  867.     {
  868.       CloseClipboard( (struct ClipboardHandle *)(iff -> iff_Stream) );
  869.  
  870.       FreeIFF( iff );
  871.     }
  872. }
  873.  
  874.  
  875. LONG StartIFFFilm( struct IFFHandle *iff, struct BitMapHeader *bmh, ULONG modeid, struct ColorRegister *cm, ULONG numcolors, struct VoiceHeader *vh )
  876. {
  877.     LONG error;
  878.  
  879.     if( !(error = OpenIFF( iff, IFFF_WRITE )) )
  880.     {
  881.       for( ;; ) /* not a loop, used as a jump table */
  882.       {
  883.         if( error = PushChunk( iff, ID_FILM, ID_LIST, IFFSIZE_UNKNOWN ) )
  884.           break;
  885.  
  886.         /* write ILBM props */
  887.         {
  888.           if( error = PushChunk( iff, ID_ILBM, ID_PROP, IFFSIZE_UNKNOWN ) )
  889.             break;
  890.  
  891.           /* write ILBM BMHD (BitMapHeader) */
  892.           {
  893.             if( error = PushChunk( iff, 0UL, ID_BMHD, IFFSIZE_UNKNOWN ) )
  894.              break;
  895.  
  896.             if( WriteChunkBytes( iff, (APTR)bmh, sizeof( struct BitMapHeader ) ) != sizeof( struct BitMapHeader ) )
  897.             {
  898.               error = IFFERR_WRITE;
  899.               break;
  900.             }
  901.  
  902.             if( error = PopChunk( iff ) )
  903.               break;
  904.           }
  905.  
  906.           /* write ILBM CAMG (amiga view mode) */
  907.           {
  908.             if( error = PushChunk( iff, 0UL, ID_CAMG, IFFSIZE_UNKNOWN ) )
  909.              break;
  910.  
  911.             if( WriteChunkBytes( iff, (APTR)(&modeid), sizeof( ULONG ) ) != sizeof( ULONG ) )
  912.             {
  913.               error = IFFERR_WRITE;
  914.               break;
  915.             }
  916.  
  917.             if( error = PopChunk( iff ) )
  918.               break;
  919.           }
  920.  
  921.           /* write ILBM CMAP (global color map) */
  922.           {
  923.             ULONG i;
  924.  
  925.             if( error = PushChunk( iff, 0UL, ID_CMAP, IFFSIZE_UNKNOWN ) )
  926.               break;
  927.  
  928.             for( i = 0UL ; i < numcolors ; i++, cm++ )
  929.             {
  930.               /* Write R, B, G bytes */
  931.               if( WriteChunkBytes( iff, (APTR)cm, 3UL ) != 3UL )
  932.               {
  933.                 error = IFFERR_WRITE;
  934.                 break;
  935.               }
  936.             }
  937.  
  938.             /* any error in loop above ? */
  939.             if( error )
  940.               break;
  941.  
  942.             if( error = PopChunk( iff ) )
  943.               break;
  944.           }
  945.  
  946.           if( error = PopChunk( iff ) )
  947.             break;
  948.         }
  949.  
  950.         /* write 8SVX props */
  951.         {
  952.           if( error = PushChunk( iff, ID_8SVX, ID_PROP, IFFSIZE_UNKNOWN ) )
  953.             break;
  954.  
  955.           {
  956.             /* write 8SVX VHDR (VoiceHeader) */
  957.             {
  958.               if( error = PushChunk( iff, 0UL, ID_VHDR, IFFSIZE_UNKNOWN ) )
  959.                 break;
  960.  
  961.               if( WriteChunkBytes( iff, (APTR)vh, sizeof( struct VoiceHeader ) ) != sizeof( struct VoiceHeader ) )
  962.               {
  963.                 error = IFFERR_WRITE;
  964.                 break;
  965.               }
  966.  
  967.               if( error = PopChunk( iff ) )
  968.                 break;
  969.             }
  970.           }
  971.           
  972.           /* a 8SVX CHAN chunk is missing here (animation.datatype does currently not support stereo sound) */
  973.  
  974.           if( error = PopChunk( iff ) )
  975.             break;
  976.         }
  977.  
  978.         break; /* end of jump table */
  979.       }
  980.  
  981.       /* All headers written successfully ? */
  982.       if( error == 0L )
  983.       {
  984.         /* Success ! */
  985.         return( 0L );
  986.       }
  987.  
  988.       CloseIFF( iff );
  989.     }
  990.  
  991.     return( error );
  992. }
  993.  
  994.  
  995. void EndIFFFilm( struct IFFHandle *iff )
  996. {
  997.     if( iff )
  998.     {
  999.       LONG error;
  1000.  
  1001.       if( error = PopChunk( iff ) )
  1002.       {
  1003.         Printf( "error while popping IFF FILM LIST %ld\n", error );
  1004.       }
  1005.  
  1006.       CloseIFF( iff );
  1007.  
  1008.       Printf( "IFF FILM sucessfully created\n" );
  1009.     }
  1010.     else
  1011.     {
  1012.       Printf( "no iff\n" );
  1013.     }
  1014. }
  1015.  
  1016.  
  1017. LONG WriteIFFFilmCell( struct IFFHandle *iff, struct BitMapHeader *bmh, struct BitMap *bm, BYTE *sample, ULONG samplelength )
  1018. {
  1019.     LONG error;
  1020.  
  1021.     for( ;; ) /* not a loop, used as a jump-table */
  1022.     {
  1023.       if( error = PushChunk( iff, ID_CELL, ID_CAT, IFFSIZE_UNKNOWN ) )
  1024.         break;
  1025.  
  1026.       /* write FORM ILBM */
  1027.       {
  1028.         if( error = PushChunk( iff, ID_ILBM, ID_FORM, IFFSIZE_UNKNOWN ) )
  1029.           break;
  1030.  
  1031.         /* Write ILBM BODY */
  1032.         if( error = PutILBMBody( iff, bm, bmh ) )
  1033.           break;
  1034.  
  1035.         if( error = PopChunk( iff ) )
  1036.           break;
  1037.       }
  1038.  
  1039.       /* write FORM 8SVX */
  1040.       {
  1041.         if( error = PushChunk( iff, ID_8SVX, ID_FORM, IFFSIZE_UNKNOWN ) )
  1042.           break;
  1043.  
  1044.         /* Write 8SVX BODY */
  1045.         if( error = Put8SVXBody( iff, sample, samplelength ) )
  1046.           break;
  1047.  
  1048.         if( error = PopChunk( iff ) )
  1049.           break;
  1050.       }
  1051.  
  1052.       if( error = PopChunk( iff ) )
  1053.         break;
  1054.  
  1055.       break; /* end of jump-table */
  1056.     }
  1057.  
  1058.     return( error );
  1059. }
  1060.  
  1061.  
  1062. LONG Put8SVXBody( struct IFFHandle *iff, BYTE *sample, ULONG samplelength )
  1063. {
  1064.     LONG error;
  1065.  
  1066.     /* Write out a BODY chunk header */
  1067.     if( error = PushChunk( iff, NULL, ID_BODY, IFFSIZE_UNKNOWN ) )
  1068.       return( error );
  1069.  
  1070.     if( WriteChunkBytes( iff, sample, samplelength ) != samplelength )
  1071.       return( IFFERR_WRITE );
  1072.  
  1073.     /* Finish the chunk */
  1074.     error = PopChunk( iff );
  1075.  
  1076.     return( error );
  1077. }
  1078.  
  1079.  
  1080. /*****************************************************************************/
  1081.  
  1082. /* from IFF example code ("iffp/ilbm.h") */
  1083. #define RowBytes( w )     ((((w) + 15) >> 4) << 1)
  1084. #define RowBits( w )      ((((w) + 15) >> 4) << 4)
  1085.  
  1086.  
  1087. LONG PutILBMBody( struct IFFHandle *iff, struct BitMap *bitmap, struct BitMapHeader *bmh )
  1088. {
  1089.     LONG     error;
  1090.     LONG     rowBytes        = bitmap -> BytesPerRow;           /* for source modulo only */
  1091.     LONG     FileRowBytes    = RowBytes( (bmh -> bmh_Width) );  /* width to write in bytes */
  1092.     ULONG    planeCnt        = bmh -> bmh_Depth;               /* number of bit planes including mask */
  1093.     ULONG    iPlane,
  1094.              iRow;
  1095.     BYTE    *planes[ 24 ]; /* array of ptrs to planes & mask */
  1096.  
  1097.     /* Copy the ptrs to bit & mask planes into local array "planes" */
  1098.     for( iPlane = 0 ; iPlane < planeCnt; iPlane++ )
  1099.        planes[ iPlane ] = (BYTE *)(bitmap -> Planes[ iPlane ]);
  1100.  
  1101.     /* Write out a BODY chunk header */
  1102.     if( error = PushChunk( iff, NULL, ID_BODY, IFFSIZE_UNKNOWN ) )
  1103.       return( error );
  1104.  
  1105.     /* Write out the BODY contents */
  1106.     for( iRow = bmh -> bmh_Height ; iRow > 0 ; iRow-- )
  1107.     {
  1108.       for( iPlane = 0 ; iPlane < planeCnt ; iPlane++ )
  1109.       {
  1110.         /* Write next row.*/
  1111.         if( WriteChunkBytes( iff, planes[ iPlane ], FileRowBytes ) != FileRowBytes )
  1112.           return( IFFERR_WRITE );
  1113.  
  1114.         planes[ iPlane ] += rowBytes; /* Possibly skipping unused bytes */
  1115.       }
  1116.     }
  1117.  
  1118.     /* Finish the chunk */
  1119.     error = PopChunk( iff );
  1120.  
  1121.     return( error );
  1122. }
  1123.  
  1124.  
  1125. /* save datatypes object with matching icon */
  1126. ULONG SaveDTObject( Object *dto, struct Window *window, struct Requester *requester, STRPTR filename, ULONG mode, struct TagItem *dtw_AttrList )
  1127. {
  1128.     ULONG retval = 0UL;
  1129.  
  1130.     if( dto && filename )
  1131.     {
  1132.       struct DataType *dtn;
  1133.  
  1134.       /* Get the object type */
  1135.       if( GetDTAttrs( dto, DTA_DataType, (&dtn), TAG_DONE ) )
  1136.       {
  1137.         BPTR fh;
  1138.  
  1139.         /* Open new file... */
  1140.         if( fh = Open( filename, MODE_NEWFILE ) )
  1141.         {
  1142.           struct dtWrite dtw;
  1143.           LONG           ioerr;
  1144.  
  1145.           /* Write... */
  1146.           dtw . MethodID       = DTM_WRITE;
  1147.           dtw . dtw_GInfo      = NULL;
  1148.           dtw . dtw_FileHandle = fh;
  1149.           dtw . dtw_Mode       = mode;
  1150.           dtw . dtw_AttrList   = dtw_AttrList;
  1151.  
  1152.           if( retval = DoDTMethodA( dto, window, requester, (Msg)(&dtw) ) )
  1153.           {
  1154.             TEXT               buffer[ 256 ];
  1155.             struct DiskObject *dobj;
  1156.  
  1157.             /* Save IoErr code because following code will clear this */
  1158.             ioerr = IoErr();
  1159.  
  1160.             if( dtn )
  1161.             {
  1162.               /* Get the an icon for the file */
  1163.               mysprintf( buffer, "ENV:Sys/def_%.240s", (dtn -> dtn_Header -> dth_BaseName) );
  1164.  
  1165.               if( (dobj = GetDiskObject( buffer )) == NULL )
  1166.               {
  1167.                 dobj = GetDefDiskObject( WBPROJECT );
  1168.               }
  1169.             }
  1170.             else
  1171.             {
  1172.               dobj = GetDefDiskObject( WBPROJECT );
  1173.             }
  1174.  
  1175.             /* If we have an icon, then write it out */
  1176.             if( dobj )
  1177.             {
  1178.               PutDiskObject( filename, dobj );
  1179.  
  1180.               FreeDiskObject( dobj );
  1181.             }
  1182.           }
  1183.           else
  1184.           {
  1185.             /* Save IoErr code because Close will clear this */
  1186.             ioerr = IoErr();
  1187.           }
  1188.  
  1189.           Close( fh );
  1190.  
  1191.           SetIoErr( ioerr );
  1192.         }
  1193.       }
  1194.       else
  1195.       {
  1196.         /* Can't get DTA_DataType */
  1197.         SetIoErr( ERROR_NO_FREE_STORE );
  1198.       }
  1199.     }
  1200.     else
  1201.     {
  1202.       /* wrong function args */
  1203.       SetIoErr( ERROR_REQUIRED_ARG_MISSING );
  1204.     }
  1205.  
  1206.     return( retval );
  1207. }
  1208.  
  1209.  
  1210. /* save sound sample using a sound.datatype object */
  1211. void SaveSample( STRPTR filename, BYTE *sample, ULONG length, ULONG period, ULONG cycles )
  1212. {
  1213.     Object *so;
  1214.  
  1215.     /* Create sound object and set it up manually (e.g. DTST_RAM) */
  1216.     if( so = NewDTObject( NULL,
  1217.                           DTA_SourceType,    DTST_RAM,
  1218.                           DTA_GroupID,       GID_SOUND,
  1219.                           SDTA_Sample,       sample,
  1220.                           SDTA_SampleLength, MAX( 1UL, length ),
  1221.                           SDTA_Period,       period,
  1222.                           SDTA_Cycles,       (ULONG)MAX( cycles, 1UL ),
  1223.                           TAG_DONE ) )
  1224.     {
  1225.       struct VoiceHeader *vh;
  1226.  
  1227.       /* Set up voiceheader, if possible... */
  1228.       if( GetDTAttrs( so, SDTA_VoiceHeader, (&vh), TAG_DONE ) )
  1229.       {
  1230.         if( vh )
  1231.         {
  1232.           vh -> vh_OneShotHiSamples     = length;
  1233.           vh -> vh_RepeatHiSamples      = 0UL;
  1234.           vh -> vh_SamplesPerHiCycle    = 0UL;
  1235.           vh -> vh_SamplesPerSec        = ((SysBase -> ex_EClockFrequency) * 5UL) / period;
  1236.           vh -> vh_Octaves              = 1UL;
  1237.           vh -> vh_Compression          = CMP_NONE;
  1238.           vh -> vh_Volume               = 0x10000UL;
  1239.         }
  1240.       }
  1241.  
  1242.       /* save the data */
  1243.       SaveDTObject( so, NULL, NULL, filename, DTWM_IFF, NULL );
  1244.  
  1245.       /* The given data (e.g. SDTA_Sample) will be freed by the application */
  1246.       SetDTAttrs( so, NULL, NULL, SDTA_Sample, NULL, TAG_DONE );
  1247.  
  1248.       /* Get rid of the sound object */
  1249.       DisposeDTObject( so );
  1250.     }
  1251. }
  1252.  
  1253.  
  1254. /* copy 32 bits-per-gun cregs table into struct ColorRegister array */
  1255. void FillColorRegisters( struct ColorRegister *cm, ULONG *cregs, ULONG numcolors )
  1256. {
  1257.     if( cm && cregs && numcolors )
  1258.     {
  1259.       ULONG i;
  1260.  
  1261.       for( i = 0UL ; i < numcolors ; i++, cm++ )
  1262.       {
  1263.         /* reduce color information from 32 bits down to 8 bits per r, g, b */
  1264.         cm -> red   = (UBYTE)(cregs[ ((i * 3) + 0) ] >> 24UL);
  1265.         cm -> green = (UBYTE)(cregs[ ((i * 3) + 1) ] >> 24UL);
  1266.         cm -> blue  = (UBYTE)(cregs[ ((i * 3) + 2) ] >> 24UL);
  1267.       }
  1268.     }
  1269. }
  1270.  
  1271.  
  1272. /* Copy bitmaps, (non-)interleaved source to (non-)interleaved destination */
  1273. void CopyBitMap( struct BitMap *dest, struct BitMap *src )
  1274. {
  1275.     if( dest && src )
  1276.     {
  1277.       PLANEPTR  splanes[ 8 ] = { 0 };
  1278.       PLANEPTR  dplanes[ 8 ] = { 0 };
  1279.       ULONG     iRow,
  1280.                 iPlane;
  1281.       ULONG     srcBytes = (IsInterleavedBitMap( src )?
  1282.                            ((src -> BytesPerRow) / (src -> Depth)):
  1283.                            (src -> BytesPerRow));
  1284.  
  1285.       for( iRow = (src -> Rows) ; iRow > 0UL ; iRow-- )
  1286.       {
  1287.         for( iPlane = 0UL ; iPlane < (ULONG)(src -> Depth) ; iPlane++ )
  1288.         {
  1289.           if( splanes[ iPlane ] == NULL ) splanes[ iPlane ] = src  -> Planes[ iPlane ];
  1290.           if( dplanes[ iPlane ] == NULL ) dplanes[ iPlane ] = dest -> Planes[ iPlane ];
  1291.  
  1292.           /* Write next row. */
  1293.           memcpy( dplanes[ iPlane ], splanes[ iPlane ], (size_t)srcBytes );
  1294.  
  1295.           splanes[ iPlane ] += src  -> BytesPerRow;
  1296.           dplanes[ iPlane ] += dest -> BytesPerRow;
  1297.         }
  1298.       }
  1299.     }
  1300. }
  1301.  
  1302.  
  1303. void mysprintf( STRPTR buffer, STRPTR fmt, ... )
  1304. {
  1305.     APTR args;
  1306.  
  1307.     args = (APTR)((&fmt) + 1);
  1308.  
  1309.     RawDoFmt( fmt, args, (void (*))"\x16\xc0\x4e\x75", buffer );
  1310. }
  1311.  
  1312.  
  1313. /* Check if given bitmap is interleaved or not. This function works even on non-chip-mem-bitmaps.
  1314.  * The V39/V40 GetBitMapAttr function don't set the interleaved flag, see above for a future-compatible
  1315.  * workaround.
  1316.  */
  1317. BOOL IsInterleavedBitMap( struct BitMap *bm )
  1318. {
  1319.     if( bm )
  1320.     {
  1321.       if( (bm -> Depth) > 1U )
  1322.       {
  1323.         if( (ULONG)((bm -> Planes[ 1 ]) - (bm -> Planes[ 0 ])) == ((ULONG)(bm -> BytesPerRow) / (ULONG)(bm -> Depth)) )
  1324.         {
  1325.           return( TRUE );
  1326.         }
  1327.       }
  1328.     }
  1329.  
  1330.     return( FALSE );
  1331. }
  1332.  
  1333.